package com.zc.component.network.tcp.device;

import com.zc.component.gateway.DeviceGateway;
import com.zc.component.gateway.supports.DeviceGatewayProperties;
import com.zc.component.gateway.supports.DeviceGatewayProvider;
import com.zc.component.network.core.DefaultNetworkType;
import com.zc.component.network.core.NetworkManager;
import com.zc.component.network.core.NetworkType;
import com.zc.component.network.tcp.client.TcpClient;
import com.zc.component.network.tcp.server.TcpServer;
import com.zc.core.ProtocolSupports;
import com.zc.core.device.DeviceRegistry;
import com.zc.core.device.session.DeviceSessionManager;
import com.zc.core.event.EventBus;
import com.zc.supports.server.DecodedClientMessageHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import reactor.core.publisher.Mono;

/**
 * TCP客户端服务设备网关提供商
 *
 * @author xiepufeng
 */
@Component
public class TcpClientDeviceGatewayProvider implements DeviceGatewayProvider {

    private final NetworkManager networkManager;

    private final DeviceRegistry registry;

    private final DeviceSessionManager sessionManager;

    private final DecodedClientMessageHandler messageHandler;

    private final ProtocolSupports protocolSupports;

    private final EventBus eventBus;


    public TcpClientDeviceGatewayProvider(NetworkManager networkManager,
                                          DeviceRegistry registry,
                                          DeviceSessionManager sessionManager,
                                          DecodedClientMessageHandler messageHandler,
                                          ProtocolSupports protocolSupports,
                                          EventBus eventBus) {
        this.networkManager = networkManager;
        this.registry = registry;
        this.sessionManager = sessionManager;
        this.messageHandler = messageHandler;
        this.protocolSupports = protocolSupports;
        this.eventBus = eventBus;
    }

    @Override
    public String getId() {
        return "tcp-client-gateway";
    }

    @Override
    public String getName() {
        return "TCP 透传连接";
    }

    @Override
    public NetworkType getNetworkType() {
        return DefaultNetworkType.TCP_CLIENT;
    }

    @Override
    public Mono<DeviceGateway> createDeviceGateway(DeviceGatewayProperties properties) {
        return networkManager
            .<TcpServer>getNetwork(getNetworkType(), properties.getNetworkId())
            .map(tcpClientServer -> {
                String protocol = (String) properties.getConfiguration().get("protocol");

                Assert.hasText(protocol, "protocol can not be empty");

                return new TcpClientDeviceGateway(properties.getId(),
                    protocol,
                    protocolSupports,
                    registry,
                    messageHandler,
                    sessionManager,
                    tcpClientServer,
                    eventBus
                );
            });
    }
}
